/*
 * @(#)Point.java     14/08/02
 * 
 * Author             Rick Wilson
 * Copyright (c) 2014 Rick Wilson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of 'Taareekah' nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */



package util;

//~--- JDK imports ------------------------------------------------------------

import java.io.Serializable;

import java.util.Vector;

/**
 *
 * @author rick
 */
public class Point implements Comparable<Point>, Serializable {

    /**
     *
     */
    protected int	x;

    /**
     *
     */
    protected int	y;

    /**
     *
     */
    public Point() {}

    /**
     *
     * @param x
     * @param y
     */
    public Point(int x, int y) {
	this.x	= x;
	this.y	= y;
    }

    /**
     *
     * @return
     */
    public int getX() {
	return x;
    }

    /**
     *
     * @return
     */
    public int getY() {
	return y;
    }

    /**
     *
     * @param x
     */
    public void setX(int x) {
	this.x	= x;
    }

    /**
     *
     * @param y
     */
    public void setY(int y) {
	this.y	= y;
    }

    /**
     *
     * @param x
     * @param y
     */
    public void set(int x, int y) {
	this.x	= x;
	this.y	= y;
    }

    /**
     *
     * @param o
     * @return
     */
    public double straightLineDistance(Point o) {
	return Math.sqrt(Math.pow((o.getX() - getX()), 2.0) + Math.pow((o.getY() - getY()), 2.0));
    }

    /**
     *
     * @param min_inclusive
     * @param max_exclusive
     * @return
     */
    public boolean withinRange(int min_inclusive, int max_exclusive) {
	if ((getX() < min_inclusive) || (getY() < min_inclusive)) {
	    return false;
	} else if ((getX() >= max_exclusive) || (getY() >= max_exclusive)) {
	    return false;
	}

	return true;
    }

    /**
     *
     * @return
     */
    public Point[] getNeighbors() {
	Point	ret[]	= new Point[8];

	// North
	ret[0]	= new Point(x, y + 1);

	// North east
	ret[1]	= new Point(x + 1, y + 1);

	// east
	ret[2]	= new Point(x + 1, y);

	// South east
	ret[3]	= new Point(x + 1, y - 1);

	// South
	ret[4]	= new Point(x, y - 1);

	// South west
	ret[5]	= new Point(x - 1, y - 1);

	// west
	ret[6]	= new Point(x - 1, y);

	// North west
	ret[7]	= new Point(x - 1, y + 1);

	return ret;
    }

    /**
     *
     * @param min_inclusive
     * @param max_exclusive
     * @return
     */
    public Vector<Point> getNeighborsWithinRange(int min_inclusive, int max_exclusive) {
	Point		neighbors[]	= getNeighbors();
	Vector<Point>	ret		= new Vector<Point>();

	for (int i = 0; i < 8; i++) {
	    if (neighbors[i].withinRange(min_inclusive, max_exclusive)) {
		ret.add(neighbors[i]);
	    }
	}

	return ret;
    }

    /**
     *
     * @param o
     * @return
     */
    public boolean areNeighbors(Point o) {
	int	d_x	= Math.abs(o.getX() - getX());
	int	d_y	= Math.abs(o.getY() - getY());

	if ((d_x > 1) || (d_y > 1)) {
	    return false;
	} else if ((d_x == 0) && (d_y == 0)) {
	    return false;
	}

	return true;
    }

    /**
     *
     * @param o
     * @return
     */
    public boolean equals(Point o) {
	if ((getX() == o.getX()) && (getY() == o.getY())) {
	    return true;
	}

	return false;
    }

    /**
     * Method description
     *
     *
     * @param o
     *
     * @return
     */
    public int compareTo(Point o) {
	if (getX() < o.getX()) {
	    return -1;
	} else if ((getX() == o.getX()) && (getY() == o.getY())) {
	    return 0;
	} else if ((getX() == o.getX()) && (getY() < o.getY())) {
	    return -1;
	}

	return 1;
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
